package org.apache.cayenne.extentions.modeler;

import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Window;
import java.io.File;

import javax.swing.JFrame;
import javax.swing.JRootPane;

import org.apache.cayenne.modeler.action.ActionManager;
import org.apache.cayenne.di.Inject;
import org.apache.cayenne.extentions.modeler.PluginActionManager;
import org.apache.cayenne.modeler.Application;
import org.apache.cayenne.modeler.CayenneModelerController;
//import org.apache.cayenne.modeler.Application.ModelerContext;
import org.apache.cayenne.modeler.dialog.LogConsole;
import org.apache.cayenne.modeler.undo.CayenneUndoManager;
import org.apache.cayenne.modeler.util.AdapterMapping;
import org.apache.cayenne.modeler.util.CayenneDialog;
import org.apache.cayenne.swing.BindingFactory;
import org.scopemvc.controller.basic.ViewContext;
import org.scopemvc.controller.swing.SwingContext;
import org.scopemvc.core.View;
import org.scopemvc.util.UIStrings;
import org.scopemvc.view.swing.SwingView;

public class PluginApplication extends Application {
	
	protected CayenneModelerController frameController;
  
	public PluginApplication(){}
//	public PluginApplication(@Inject File initialProject) {
//		//super(initialProject);
//	}

//	@Override
//	protected CayenneModelerController initFrameController() {
//		return new PluginModelerController(this, initialProject);
//
//	}

	@Override
	public ActionManager getActionManager() {
        return injector.getInstance(PluginActionManager.class);
    }
	
	@Override
	 public CayenneModelerController getFrameController() {
        return frameController;
    }
	
	@Override
	 public void startup() {
        // init subsystems
        initPreferences();
        initClassLoader();

        this.bindingFactory = new BindingFactory();
        this.adapterMapping = new AdapterMapping();

        // ...Scope

        // TODO: this will go away if switch away from Scope
        // force Scope to use CayenneModeler properties
        UIStrings.setPropertiesName(DEFAULT_MESSAGE_BUNDLE);
        ViewContext.clearThreadContext();

        this.undoManager = new CayenneUndoManager(this);

        this.frameController = new PluginModelerController(this);

        // update Scope to work nicely with main frame
        Application ap = new Application();
       
        ViewContext.setGlobalContext(new ModelerContext(frameController.getFrame()));

        // open up
        frameController.startupAction();

        // After prefs have been loaded, we can now show the console if needed
        LogConsole.getInstance().showConsoleIfNeeded();
        getFrame().setVisible(true);
    }
	final class ModelerContext extends SwingContext {

        JFrame frame;

        public ModelerContext(JFrame frame) {
            this.frame = frame;
        }

        @Override
        protected void showViewInPrimaryWindow(SwingView view) {
        }

        /**
         * Creates closeable dialogs.
         */
        @Override
        protected void showViewInDialog(SwingView inView) {
            // NOTE:
            // copied from superclass, except that JDialog is substituted for
            // CayenneDialog
            // Keep in mind when upgrading Scope to the newer versions.

            // Make a JDialog to contain the view.
            Window parentWindow = getDefaultParentWindow();

            final CayenneDialog dialog;
            if (parentWindow instanceof Dialog) {
                dialog = new CayenneDialog((Dialog) parentWindow);
            }
            else {
                dialog = new CayenneDialog((Frame) parentWindow);
            }

            // Set title, modality, resizability
            if (inView.getTitle() != null) {
                dialog.setTitle(inView.getTitle());
            }
            if (inView.getDisplayMode() == SwingView.MODAL_DIALOG) {
                dialog.setModal(true);
            }
            else {
                dialog.setModal(false);
            }
            dialog.setResizable(inView.isResizable());

            setupWindow(dialog.getRootPane(), inView, true);
            dialog.toFront();
        }

        /**
         * Overrides super implementation to allow using Scope together with normal Swing
         * code that CayenneModeler already has.
         */
        @Override
        public JRootPane findRootPaneFor(View view) {
            JRootPane pane = super.findRootPaneFor(view);

            if (pane != null) {
                return pane;
            }

            if (((SwingView) view).getDisplayMode() != SwingView.PRIMARY_WINDOW) {
                return pane;
            }

            return frame.getRootPane();
        }

        @Override
        protected Window getDefaultParentWindow() {
            return frame;
        }
    }
	
}